Developer Documentation

QuickTime 4 API Documentation

QuickTime For Windows Programmers

| Previous | Chapter Contents | Chapter Top | Roadmap | Next |

Graphics Worlds

Another aspect of the graphics environment that affects the way QuickTime displays images on the screen is the characteristics of the graphics device on which they're being presented. These include such things as the device's pixel resolution, its color depth, and the capacity of its color table. The device's characteristics are summarized in a graphics device record (described in detail in Mac OS For QuickTime Programmers.

Ordinarily, the results of a program's drawing operations depend on the graphical capabilities of the display device that happens to be connected to the user's computer at run time. There can even be more than one such device attached to the same system: QTML will figure out which screen is being drawn to and will display all results correctly according to the characteristics of each device. All of this normally happens automatically, and is transparent to the running program.

Sometimes, however, a program may need to take a more active role in controlling the graphics environment for its drawing operations. If you're creating a QuickTime movie, for instance, you probably don't want to define the movie's appearance in terms of the display characteristics of a particular graphics device. Rather, you want the movie's content to be device-independent, with its own inherent dimensions, pixel depth, colors, and so on. Then, when the movie is displayed on a user's computer, QuickTime will automatically adapt its graphical characteristics to those of the available display device, and will present the movie as faithfully as it can on the given device.

The way to accomplish this is to define the movie with respect to a device-independent graphics world . This combines a graphics port and a device record, which together completely determine the graphics environment in which QuickTime does its drawing. Like the window record we discussed in the preceding section, the data structure representing a graphics world is an extended graphics port with some additional fields appended at the end. The exact details are private to QTML; the graphics world is always referred to by means of an opaque pointer of type GWorldPtr . Because the underlying structure is based on a graphics port, however, this pointer is equated to a graphics port pointer:

typedef CGrafPtr GWorldPtr;

This means that (again like a window record), a graphics world can be used anywhere a graphics port would be expected: for instance, as an argument to the MacSetPort function that sets the current port for subsequent drawing operations.

A graphics world's device record can represent an existing physical graphics device, but it need not: it can also describe a fictitious "offscreen" device with any graphical characteristics you choose. You create such an offscreen graphics world by specifying the desired characteristics as parameters to the QTML function NewGWorld :

QDErr
    NewGWorld
        (GWorldPtr *offscreenGWorld, // Returns pointer to GWorld
         short pixelDepth,      // Color depth in bits per pixel
         const Rect *boundsRect,      // Boundary rectangle
         CTabHandle cTable,          // Handle to color table
         GDHandle aGDevice,        // Set to null for offscreen
         GWorldFlags flags);          // Option flags

You can read all about this function and its parameters in Mac OS For QuickTime Programmers. What's relevant here is that if the noNewDevice flag in the flags parameter is clear, the function will ignore the parameter aGDevice and create a new, device-independent device record with the specified characteristics. It will then combine this device record with a graphics port for drawing into a memory-based image buffer (rather than directly to the screen), and will return a pointer to the resulting graphics world via the offscreenGWorld parameter.

Note, however, that when you use NewGWorld to create your graphics world, it will be set up to draw into a Macintosh-style bitmap as its image buffer. If you want to work with a Windows-style bitmap instead, you can use an alternate function available only in the Windows version of the QuickTime API:

QDErr
    NewGWorldFromHBITMAP
        (GWorldPtr *offscreenGWorld,   // Returns pointer to GWorld
         CTabHandle cTable,            // Handle to color table
         GDHandle aGDevice,          // Set to null for offscreen
         GWorldFlags flags,             // Option flags
         void *newHBITMAP,        // Handle to bitmap
         void *newHDC)            // Handle to device context
         long          rowBytes)          // number of bytes in a
                                                            scanline

The parameters newHBITMAP and newHDC must either both be null or handles to a Windows bitmap and device context, respectively. If they're null, the function will allocate a complete graphics world for you; otherwise, it will simply wrap one around the specified structures. This allows you to use the native Windows drawing environment as the source for QuickTime operations such as image compression or CopyBits . If you do supply a Windows bitmap, it must be a device-independent bitmap (DIB) created with the Windows function CreateDIBSection . All other parameters are as described in Mac OS For QuickTime Programmers, with the exception of the pixelFormat parameter that replaces pixelDepth in the original NewGWorld function. Valid settings for this parameter are as follows:

    0                               // Default
    k1MonochromePixelFormat
    k2IndexedPixelFormat
    k4IndexedPixelFormat
    k8IndexedPixelFormat
    k1IndexedGrayPixelFormat
    k2IndexedGrayPixelFormat
    k4IndexedGrayPixelFormat
    k8IndexedGrayPixelFormat
    k16BE555PixelFormat
    k32ARGBPixelFormat
    
    k16LE555PixelFormat
    k16LE565PixelFormat
    k24BGRPixelFormat
    k24RGBPixelFormat
    k32BGRAPixelFormat
    k32ABGRPixelFormat
    k32RGBAPixelFormat

Once you've created a graphics world to your specifications, you can use it to set the current graphics port and device, then you can proceed to create your movie. The QTML function SetGWorld

void
    SetGWorld
        (CGrafPtr port,       // Port or graphics world to make current
         GDHandle gdh)        // Device to make current

nominally accepts a graphics port and device record and makes them the current port and current device. However, if the port parameter actually points to a graphics world (remember that data types GWorldPtr and CGrafPtr are equivalent), then the function ignores parameter gdh and uses the port and device from the given graphics world instead. A companion function, GetGWorld

void
    GetGWorld
        (CGrafPtr *port,       // Returns current port
         GDHandle *gdh)        // Returns current device

returns a pointer to the current port and a handle to the current device record. You can use this function, for example, to save the previous current port and device and restore them again after you're finished creating your movie. Listing 5 shows an example.

Listing 5 Using an offscreen graphics world

CGrafPtr oldPort;                        // Previous current port
GDHandle oldDevice;                      // Previous current device
GWorldPtr movieGWorld = nil;              // Movie's graphics world
Rect movieFrame;                     // Boundary rectangle for movie images
OSErr errCode;                        // Result code

        ·                       
        ·

errCode = NewGWorld (&movieGWorld,          // Return result in movieGWorld
                     16,                    // Pixel depth
                     &movieFrame,           // Boundary rectangle
                     nil,                   // Use default color table
                     nil,                   // No preexisting device record
                     0 );                   // No flags to pass

if ( errCode != noErr )                     // Was there an error?
    MessageBox (hWnd, "Error creating graphics world", "", MB_OK); // Notify user
    
else
    {   
        GetGWorld (&oldPort, &oldDevice);   // Save previous graphics world
        SetGWorld (movieGWorld, nil);       // Set movie's graphics world
            
            /* Here...you would draw images */
            
        SetGWorld (oldPort, oldDevice);     // Restore previous graphics world
        
        DisposeGWorld (movieGWorld);        // Dispose of movie's graphics world
        
    } /* end else */

Besides the general SetGWorld and GetGWorld functions, the QuickTime Movie Toolbox also provides a pair of functions for setting and retrieving a movie's graphics world directly:

void
    SetMovieGWorld
        (Movie theMovie,
         CGrafPtr port,
         GDHandle gdh)
void
    GetMovieGWorld
        (Movie theMovie,
         CGrafPtr *port,
         GDHandle *gdh)

This is useful for drawing offscreen because you can create GWorlds and then direct the movie to draw them there.

Like SetGWorld , SetMovieGWorld will accept a graphics world as its first parameter in place of a graphics port; it will then ignore the second parameter and use the device record from the graphics world instead.


© 1998 Apple Computer, Inc.

| Previous | Chapter Contents | Chapter Top | Roadmap | Next |